<!--
*@Author: zt
*@Description: 知识库
*@Date: 2024-08-22
-->
<template>
  <a-layout
    class="f-h-100"
    style="background-color: unset">
    <a-layout-header
      class="u-knowledge-header"
      style="height: 120px; padding: 0">
      <div
        class="f-flex-column"
        style="width: 100%; height: 100%; justify-content: flex-end">
        <a-row
          class="f-font-family u-span-title"
          justify="center">
          <a-popover
            :arrow="false"
            placement="bottom"
            v-model:open="showTip"
            trigger="hover">
            <template #content>
              <a-row>
                <a-tag
                  v-for="item in history"
                  closable
                  color="#2db7f5"
                  @click="(searchF.model.keywords = item), getSearch()"
                  @close="closeHis(item)">
                  {{ item }}
                </a-tag>
              </a-row>
            </template>
            <a-input-search
              style="width: 80%"
              enter-button
              size="large"
              allowClear
              v-model:value="searchF.model.keywords"
              @search="onSearchEnter">
              <template #enterButton>
                <a-button>Custom</a-button>
              </template>
            </a-input-search>
          </a-popover>
        </a-row>
        <a-row
          class="f-font-family u-span-title"
          justify="center">
          <a-space style="width: 80%; height: max-content; overflow: hidden">
            <div style="width: 70px">
              <b class="f-margin-r6">搜索历史</b>
            </div>
            <a-tag
              v-for="item in historyLen"
              closable
              @click="(searchF.model.keywords = item), getSearch(1)"
              @close="closeHis(item)">
              {{ item }}
            </a-tag>
          </a-space>
        </a-row>
      </div>
    </a-layout-header>
    <a-layout
      class="f-h-100 f-margin-t12"
      style="border-radius: 16px; overflow: hidden">
      <a-layout-sider
        theme="light"
        style="height: 100%; padding: 16px 0; border-right: 1px solid #d9d9d9">
        <div style="height: calc(100% - 40px)">
          <a-list
            :grid="{ column: 1 }"
            :data-source="classifyData"
            style="height: 65vh; overflow-y: auto">
            <template #renderItem="{ item }">
              <a-list-item
                style="padding: 0 16px; margin-block-end: 0"
                class="f-cursor">
                <a-row
                  style="padding: 8px"
                  :class="{ 'u-sider-active': siderCurrent == item.typename }"
                  @click="
                    siderCurrent = item.typename;
                    startIndex = 0;
                    searchF.model.ftype = item.keyid;
                    getSearch(1);
                  ">
                  <div style="display: flex; justify-content: space-between; width: 100%">
                    <div>
                      <u-icon-font
                        :type="POLICY_TYPE_ICON[item.keyid] || 'icon-xitongguanli'"
                        style="color: #1890ff"></u-icon-font>
                      <span class="u-span-sider-span f-font-family spanTypeName">
                        {{ item.typename }}
                      </span>
                    </div>
                    <a-popconfirm
                      title="确定删除吗?"
                      ok-text="确定"
                      cancel-text="关闭"
                      @confirm="delClassify">
                      <SmallDashOutlined :rotate="90" />
                    </a-popconfirm>
                  </div>
                </a-row>
              </a-list-item>
            </template>
          </a-list>
        </div>
        <div style="height: 40px; display: flex; justify-content: center">
          <u-icon-button @click="addClassify">新增分类</u-icon-button>
        </div>
      </a-layout-sider>
      <a-layout-content>
        <a-layout
          class="f-h-100"
          style="background: #fff">
          <u-table-header>
            <a-space
              size="middle"
              class="f-padding-b12">
              <u-icon-button
                itype="add"
                @click="addEdit"
                v-if="userInfo['extra']['roles']['1'] && userInfo['extra']['roles']['1'].length > 0">
                新增上传
              </u-icon-button>
              <u-icon-button
                itype="delete"
                @click="deleteBtn()"
                v-if="userInfo['extra']['roles']['1'] && userInfo['extra']['roles']['1'].length > 0">
                批量删除
              </u-icon-button>
            </a-space>
          </u-table-header>
          <u-table-content style="height: 100%; overflow: auto">
            <u-table
              :columns="columns"
              v-model:pagination="pagenation"
              :data="tabData"
              :loading="loading"
              @onSelect="({ selectedRows }) => (tabSelData = selectedRows)"
              @change="getSearch"></u-table>
          </u-table-content>
        </a-layout>
      </a-layout-content>
    </a-layout>
  </a-layout>

  <u-upload
    v-model:open="showAddEdit"
    title="知识库上传"
    width="800px"
    :confirmLoading="saveLoading"
    :fileParams="{
      bucket: 'DOC_BIZ_TYPE_POLICY',
      biztype: '1',
    }"
    @submit="submit"></u-upload>

  <u-dialog
    v-model:open="showClassify"
    title="新增分类"
    @submit="submitClassify"
    @close="typename = ''">
    <a-form-item
      label="分类名"
      class="f-padding-tb20">
      <u-input v-model:value="typename"></u-input>
    </a-form-item>
  </u-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, h, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { PlusOutlined, CloudDownloadOutlined } from "@ant-design/icons-vue";
import { useOtherStore } from "@/store";
import { urlFile } from "@/util/common";
import { alertC, messageC } from "@/util/common";
import { useTableScroll } from "@/hooks/useTable";
import { datas } from "./data";
import { cloneDeep } from "lodash";
import { usePreview, useDownload } from "@/hooks/useFile";
import { Button, Space, Image } from "ant-design-vue";
import { useBaseStore, useLoginStore } from "@/store";
import { storeToRefs } from "pinia";
import UIconFont from "@/components/common/iconfont/IconFont.vue";
import AddEdit from "./AddEdit.vue";
import dayjs from "dayjs";
import * as knowledgeApi from "@/service/assist/knowledge";

const { params } = storeToRefs(useOtherStore());
const { userInfo } = storeToRefs(useLoginStore());
const { POLICY_TYPE } = storeToRefs(useBaseStore());
const POLICY_TYPE_ICON = {
  1: "icon-caozuoguifan",
  2: "icon-anquanzhidu",
  3: "icon-biaozhunguifan",
  4: "icon-falvfagui",
  5: "icon-guizhangzhidu",
};
const router = useRouter();

const showAddEdit = ref(false);
const saveLoading = ref(false);
const addAddEditTitle = ref(`新增文档`);
// 新增
const addEdit = () => {
  if (!searchF.model.ftype) {
    return alertC("请选择【全部】以外的类型进行新增！");
  }
  showAddEdit.value = true;
};
const tabSelData = ref([]);

// 删除功能
const deleteBtn = async (keyid?: string) => {
  let ids = [];
  if (keyid) {
    ids.push(keyid);
  } else {
    if (tabSelData.value.length == 0) {
      alertC("请先选择要删除的数据！");
      return;
    }
    tabSelData.value.map((item) => ids.push(item.keyid));
  }
  const res = await knowledgeApi.del({ ids: ids.join(",") });
  if (res.code == 0) {
    alertC(res.msg, "success");
    getSearch();
  } else {
    alertC(res.msg, "warning");
  }
};

let siderCurrent = ref<string>("全部");
const siderData = ref<any[]>();
const siderClick = (data) => {
  siderCurrent.value = data.value;
};

const fileType = {
  doc: "word",
  docx: "word",
  xls: "excel",
  xlsx: "excel",
  pdf: "pdf",
};

const initLoading = ref<boolean>(false);
const loading = ref<boolean>(false);

let pagenation = reactive({
  total: 0,
  current: 1,
  pageSize: 10,
  showTotal: (total) => `共 ${total} 条`,
});

// 查询
const searchF = reactive({
  model: {
    keywords: "",
    ftype: "",
  },
});
const searchEl: Array<_IFormEl> = [
  {
    label: "模糊查询",
    key: "option",
    element: "input",
    col: { span: 5 },
    formItemProps: { labelWidth: "80px", wrapperCol: 24 },
    componentProps: { placeholder: "搜索知识库标题或内容" },
  },
];

// 列表
const tabData = ref<any[]>([]);
let columns: Array<TableColumnProps> = reactive([
  {
    dataIndex: "index",
    title: "序号",
    width: 60,
    align: "center",
    customRender: ({ text, record, index }) => {
      return index + 1;
    },
  },
  {
    dataIndex: "filename",
    title: "标题",
    minWidth: 100,
    customRender: ({ text, record }) => {
      let sffix = text.split(".");
      return h(Space, () => [
        h(Image, {
          src: urlFile(`knowledge/${fileType[sffix[sffix.length - 1]]}.png`),
          width: 16,
          preview: false,
        }),
        h(
          Button,
          {
            type: "link",
            onClick: () => usePreview(record.filepath),
            style: { padding: "4px 0" },
          },
          () => text
        ),
      ]);
    },
  },
  { dataIndex: "type", title: "类型", width: 150, align: "center" },
  {
    dataIndex: "updatetime",
    title: "上传时间",
    width: 150,
    align: "center",
    customRender: ({}) => {
      return dayjs().format("YYYY-MM-DD");
    },
  },
  {
    dataIndex: "do",
    title: "操作",
    width: 150,
    align: "center",
    fixed: "right",
    customRender: ({ text, record }) => {
      return h(Space, { size: 40, style: { fontSize: "16px", color: "#1890ff" } }, () => [
        h(UIconFont, {
          type: "icon-a-lujing12",
          onClick: () => useDownload(record),
        }),
        h(UIconFont, {
          type: "icon-a-shanchu1",
          onClick: () => {
            if (userInfo.value["extra"]["roles"]["1"] && userInfo.value["extra"]["roles"]["1"].length > 0) {
              deleteBtn(record.keyid), console.log(record, "record");
            }
          },
        }),
      ]);
    },
  },
]);

// 数据
let currentItem = ref<string>();
let startIndex = ref<number>(0);
let storeData = ref<any[]>([]);

const showTip = ref<boolean>(false);
const history = ref<string[]>([]);
const historyLen = computed(() => cloneDeep(history.value).reverse().slice(0, 5));

onMounted(() => {
  siderData.value = datas.filter((item) => ["1", "2"].includes(item.type));
  siderData.value.forEach((item) => (item.icon = "icon-guanzhuqiyeguanli"));

  history.value = JSON.parse(localStorage.getItem("_k_his") || "[]");
  getClassify();
  getSearch();
});

/**
 *@Author: QWP
 *@Description:列表查询
 *@Date 2024-08-26 20:18
 */
const getSearch = (current?: number) => {
  if (current == 1) {
    searchF.current = current;
  }

  if (Object.values(params.value).length != 0) {
    siderCurrent.value = params.value["name"];
    startIndex.value = 0;
    searchF.model.ftype = params.value["type"];
  }

  loading.value = true;
  searchF.size = pagenation.pageSize;
  searchF.current = pagenation.current;
  knowledgeApi
    .page(searchF)
    .then((res) => {
      loading.value = false;
      if (res.code == 0) {
        tabData.value = res.data.records;
        tabData.value.map((e) => {
          if (e.filename) {
            e["type"] = e.filename.split(".")[e.filename.split(".").length - 1];
          }
        });
        pagenation.total = res.data.total;
      }
    })
    .catch(() => (loading.value = false));
};
let showClassify = ref(false);
/**
 * 知识库新增分类
 */
const addClassify = () => {
  showClassify.value = true;
};

let classifyData = ref();
let typename = ref("");

/**
 * 知识库类查询
 */
const getClassify = async () => {
  const fromClassify = {
    model: {},
    size: 50,
    current: 1,
  };
  const res = await knowledgeApi.docPage(fromClassify);
  if (res.code == 0) {
    classifyData.value = res.data.records;
    classifyData.value.unshift({ typename: "全部", keyid: "" });
  }
};
/**
 * 知识库类提交
 */
const submitClassify = async () => {
  const res = await knowledgeApi.docAdd({ typename: typename.value });
  if (res.code == 0) {
    alertC(res.msg, "success");
    showClassify.value = false;
    typename.value = "";
    getClassify();
  }
};

/**
 * 知识库类删除
 */
const delClassify = async () => {
  if (!searchF.model.ftype) {
    return alertC("请先选择要删除的数据！");
  }
  const res = await knowledgeApi.docDel({ ids: searchF.model.ftype });
  if (res.code == 0) {
    alertC(res.msg, "success");
    getClassify();
    searchF.model.ftype = "";
    getSearch(1);
  } else {
    alertC(res.msg, "warning");
  }
};

/**
 *@Author: QWP
 *@Description: 上传保存
 *@Date 2024-08-26 20:18
 */
const submit = async (fileList: any[]) => {
  fileList.forEach((item, index) => {
    item.orderno = index;
  });
  saveLoading.value = true;
  try {
    const res = await knowledgeApi.add({
      appendixSaveVOList: fileList,
      ftype: searchF.model.ftype,
    });
    if (res.code == 0) {
      messageC(res.msg);
      showAddEdit.value = false;
      getSearch(1);
    } else {
      messageC(res.msg, "error");
    }
  } catch (error) {}
  saveLoading.value = false;
};

// 查询，回车
const onSearchEnter = (val) => {
  getSearch(1);
  if (!history.value.some((i) => i == val) && val) {
    history.value.push(val);
    localStorage.setItem("_k_his", JSON.stringify(history.value));
  }
};

// 删除历史
const closeHis = (val) => {
  history.value = history.value.filter((i) => i != val);
  localStorage.setItem("_k_his", JSON.stringify(history.value));
};

watch(
  () => params.value,
  (nval, oval) => {
    if (Object.values(nval).length != 0) {
      getSearch(1);
    }
  },
  { immediate: true }
);
</script>

<style lang="scss" scoped>
:deep(.u-knowledge-header) {
  border-radius: 16px;
  overflow: hidden;
  background: url("./../../../../assets/knowledge/headerBg.png");
  background-size: 100% 100%;
}
.u-span-title {
  font-weight: 600;
  font-size: var(--font-size-level-2);
  color: #333333;
}
.u-span-sider-span {
  font-weight: 400;
  font-size: var(--font-size-level-1);
  color: #333333;
}
.u-sider-icon {
  font-size: 18px;
  color: #aaa;
}
.u-sider-active {
  background: rgba(24, 144, 255, 0.2);
  border-radius: 0px 0px 0px 0px;
  font-weight: 400;
  font-size: var(--font-size-level-1);
  .u-span-sider-span {
    color: #1890ff;
  }
  .u-sider-icon {
    color: #1890ff;
  }
}
:deep(.u-knowledge-list) {
  // .ant-spin-container {
  //   .ant-row {
  //     div {
  //       height: 200px
  //     }
  //   }
  // }
  .u-list-item {
    padding: 0;
    height: max-content;
    background: #ffffff;
    box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
    overflow: hidden;
    .u-list-item-label {
      padding: 11px 20px;
      .u-title {
        display: inline-block;
        max-width: 100%;
        font-weight: 400;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        font-size: var(--font-size-level-1);
        color: #333333;
      }
      .u-desc {
        font-weight: 400;
        font-size: var(--font-size-level-0);
        color: #666666;
      }
    }
  }
}
.spanTypeName {
  margin-left: 10px;
}
:deep(.u-list-item-active) {
  border-radius: 8px;
  // border: 1px solid #1890FF;
  box-shadow: 0px 0 4px 0px #1890ff;
  // box-shadow: unset
}
</style>
